package main

import(
	"net"
	"strings"
)

type User struct{
	Name    string
	Addr    string
	channel chan string
	conn    net.Conn

	server *Server
}

func NewUser(conn net.Conn, server *Server) *User {
	userAddr := conn.RemoteAddr().String()

	user := &User{
		Name:    userAddr,
		Addr:    userAddr,
		channel: make(chan string),
		conn:    conn,

		server:  server,
	}

	go user.ListenMessage()

	return user
}

func (this *User)Online()  {
	this.server.mapLock.Lock()
	this.server.OnlineMap[this.Name] = this
	this.server.mapLock.Unlock()

	this.server.Broadcast(this," online.")
}

func (this *User)Offline()  {
	this.server.mapLock.Lock()
	delete(this.server.OnlineMap, this.Name)
	this.server.mapLock.Unlock()

	this.server.Broadcast(this," offline.")
}

func (this *User)SendMessage(msg string)  {
	this.conn.Write([]byte(msg + "\n"))
}

func (this *User)DoMessage(msg string)  {
	if msg == "who"{

		this.server.mapLock.Lock()

		for _,user := range this.server.OnlineMap{
			onlineMsg := "[" + user.Addr + "]" + user.Name + " is online"
			this.SendMessage(onlineMsg)
		}

		this.server.mapLock.Unlock()

	} else if len(msg) > 7 && msg[0:7] == "rename "{

		newName := strings.Split(msg, " ")[1]
		_, ok := this.server.OnlineMap[newName]
		if ok {
			this.SendMessage("This name has been used.\n")
		} else {
			this.server.mapLock.Lock()
			delete(this.server.OnlineMap, this.Name)
			this.server.OnlineMap[newName] = this
			this.server.mapLock.Unlock()

			this.Name = newName
			this.SendMessage("You have update your name : " + this.Name + "\n")
		}

	} else if len(msg) > 3 && msg[0:3] == "to " {
		toName := strings.Split(msg," ")[1]
		if toName == "" {
			this.SendMessage("Correct format is :to who what\n")
			return
		}

		toUser, ok := this.server.OnlineMap[toName]
		if !ok {
			this.SendMessage("This user not exist.\n")
			return 
		}

		sendMessage := strings.Split(msg, " ")[2]
		if sendMessage == "" {
			this.SendMessage("You have to say something.\n")
			return 
		}
		toUser.SendMessage(this.Name + " said : " + sendMessage)


	} else {
		this.server.Broadcast(this, msg)
	}
}

func (this *User) ListenMessage()  {
	for{
		msg := <- this.channel
		this.conn.Write([]byte(msg + "\n"))
	}
}

